using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Matrix.Configuration.Constants;

namespace Matrix.Configuration
{
    /// <summary>
    /// Matrix配置管理数据库上下文
    /// </summary>
    public class MatrixConfigurationDbContext : AbpDbContext<MatrixConfigurationDbContext>, IMatrixConfigurationDbContext
    {
        /// <summary>
        /// 配置项
        /// </summary>
        public DbSet<ConfigurationItem> ConfigurationItems { get; set; } = null!;

        /// <summary>
        /// 配置缓存项
        /// </summary>
        public DbSet<ConfigurationCacheItem> ConfigurationCacheItems { get; set; } = null!;

        public MatrixConfigurationDbContext(DbContextOptions<MatrixConfigurationDbContext> options)
            : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.ConfigureMatrixConfiguration();

            /* 基础配置 */
            // 这里可以添加特定的配置
        }
    }

    /// <summary>
    /// ModelBuilder扩展方法
    /// </summary>
    public static class MatrixConfigurationDbContextModelCreatingExtensions
    {
        public static void ConfigureMatrixConfiguration(this ModelBuilder builder)
        {
            Check.NotNull(builder, nameof(builder));

            // 配置ConfigurationItem实体
            builder.Entity<ConfigurationItem>(b =>
            {
                b.ToTable("ConfigurationItems");

                // 配置主键
                b.HasKey(x => x.Id);

                // 根据性能优化文档配置高性能索引
                // 核心复合索引：多租户查询的主要索引
                b.HasIndex(x => new { x.TenantId, x.Namespace, x.Key, x.IsDeleted })
                    .HasDatabaseName("IX_ConfigurationItems_Composite_Tenant_Namespace_Key_Deleted");

                // 命名空间键组合索引（用于未删除记录）
                b.HasIndex(x => new { x.Namespace, x.Key })
                    .HasFilter("\"IsDeleted\" = false")
                    .HasDatabaseName("IX_ConfigurationItems_Namespace_Key_NotDeleted");

                // 租户查询索引（用于未删除记录）
                b.HasIndex(x => x.TenantId)
                    .HasFilter("\"IsDeleted\" = false")
                    .HasDatabaseName("IX_ConfigurationItems_TenantId_NotDeleted");

                // 分页查询索引：创建时间排序
                b.HasIndex(x => new { x.CreationTime, x.TenantId })
                    .HasDatabaseName("IX_ConfigurationItems_CreationTime_TenantId");

                // 批量操作优化索引：最后修改时间
                b.HasIndex(x => new { x.TenantId, x.Namespace, x.Key, x.LastModificationTime })
                    .HasDatabaseName("IX_ConfigurationItems_BatchLookup_Tenant_Namespace_Key_ModifiedTime");

                // 保持原有的基础索引
                b.HasIndex(x => new { x.TenantId, x.Namespace, x.Key })
                    .IsUnique()
                    .HasDatabaseName("IX_ConfigurationItems_TenantId_Namespace_Key");

                b.HasIndex(x => x.Namespace)
                    .HasDatabaseName("IX_ConfigurationItems_Namespace");

                b.HasIndex(x => x.Key)
                    .HasDatabaseName("IX_ConfigurationItems_Key");

                b.HasIndex(x => x.Version)
                    .HasDatabaseName("IX_ConfigurationItems_Version");

                // 配置属性
                b.Property(x => x.Namespace)
                    .IsRequired()
                    .HasMaxLength(ConfigurationItemConsts.MaxNamespaceLength);

                b.Property(x => x.Key)
                    .IsRequired()
                    .HasMaxLength(ConfigurationItemConsts.MaxKeyLength);

                b.Property(x => x.Value)
                    .IsRequired()
                    .HasMaxLength(ConfigurationItemConsts.MaxValueLength);

                b.Property(x => x.DataType)
                    .IsRequired()
                    .HasMaxLength(ConfigurationItemConsts.MaxDataTypeLength);

                b.Property(x => x.Category)
                    .IsRequired()
                    .HasMaxLength(ConfigurationItemConsts.MaxCategoryLength);

                b.Property(x => x.Description)
                    .HasMaxLength(ConfigurationItemConsts.MaxDescriptionLength);

                b.Property(x => x.Version)
                    .IsRequired();

                // 配置租户过滤
                b.ConfigureByConvention();

                // 配置导航属性 - ExtraProperties是ABP框架自动处理的
                // 无需手动配置
            });

            // 配置ConfigurationCacheItem实体
            builder.Entity<ConfigurationCacheItem>(b =>
            {
                b.ToTable("ConfigurationCacheItems");

                // 配置主键
                b.HasKey(x => x.Id);

                // 配置索引
                b.HasIndex(x => x.CacheKey)
                    .IsUnique()
                    .HasDatabaseName("IX_ConfigurationCacheItems_CacheKey");

                b.HasIndex(x => x.ExpiryTime)
                    .HasDatabaseName("IX_ConfigurationCacheItems_ExpiryTime");

                // 配置属性
                b.Property(x => x.CacheKey)
                    .IsRequired()
                    .HasMaxLength(ConfigurationCacheItemConsts.MaxCacheKeyLength);

                b.Property(x => x.ValueType)
                    .IsRequired()
                    .HasMaxLength(ConfigurationCacheItemConsts.MaxValueTypeLength);

                b.Property(x => x.ExpiryTime)
                    .IsRequired();

                // 配置租户过滤
                b.ConfigureByConvention();
            });
        }
    }
}